package com.bt.lms.ui.action.course;

import com.alibaba.fastjson.JSON;
import com.bt.lms.constants.CourseBizTypeConstant;
import com.bt.lms.entity.CourseInfo;
import com.bt.lms.network.msg.RespMsg;
import com.bt.lms.ui.action.course.vo.CourseVo;
import com.bt.lms.network.msg.ReqMsg;
import com.bt.lms.ui.page.common.action.pageteaching.CourseLabLabAction;
import com.bt.lms.ui.page.course.AddPage;
import com.bt.lms.ui.page.course.CourseInfoList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import org.apache.commons.beanutils.BeanUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;

/**
 * 新增课程保存按钮事件
 */
public class AddCourseSaveBtnAction implements EventHandler {

    private AddPage pageAddCourse; //新增课程界面

    public AddCourseSaveBtnAction(AddPage pageAddCourse) {
        this.pageAddCourse = pageAddCourse;
    }

    @Override
    public void handle(Event event) {

        //1.获取用户输入，返回VO：里面承载着用户的输入
        CourseVo courseVo = getInParams();//获取参数
        //2.验证用户输入，inP:VO outP:消息
        String validateMsg = validateInParam(courseVo);
        //3.组包（根据自定义的网络消息协议），inP:VO outP:消息
        byte[] bytes = null;
        if (null == validateMsg) {

            //验证通过，组包
            bytes = handle2ReqMsg(courseVo);

        } else {
            //提示，程序终止
            return;
        }

        //4.组网（根据咱们自定义的网络连接交互规范来定义）inP:服务器的信息（ip,port....）
        Socket socket = getNet();
        //5.发送消息，inP:消息 ouP:是否发送成熟
        boolean flag = send(socket, bytes);

    }

    /**
     * 发送信息
     * 1.将消息转为字节流
     * 2.发送
     *
     * @param socket 发送的socket
     * @param bytes  要发送的消息
     * @return
     */
    private boolean send(Socket socket, byte[] bytes) {

        try {
            //发送消息
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(bytes); //写
            outputStream.flush();//冲刷

            //接收回应信息
            InputStream in = socket.getInputStream();
            byte[] buf = new byte[1024];
            in.read(buf); //读
            RespMsg respMsg = RespMsg.toRespMsg(buf);
            String data = respMsg.getData();

        } catch (IOException e) {
//            throw new RuntimeException(e);
        }

        return true;
    }


    /**
     * 获取网络
     *
     * @return socket
     */
    private Socket getNet() {

        String serverIp = "127.0.0.1";
        int serverPort = 8888;
        Socket socket = null;

        try {
            socket = new Socket(serverIp, serverPort);
        } catch (IOException e) {
//            throw new RuntimeException(e);
            return null;
        }

        return socket;
    }


    /**
     * 将用户输入的信息处理成我们规定的请求信息
     * 组包
     *
     * @param courseVo 用户输入
     * @return 请求消息
     */
    private byte[] handle2ReqMsg(CourseVo courseVo) {

        //消息
        ReqMsg reqMsg = new ReqMsg();

        //课程信息
        CourseInfo courseInfo = new CourseInfo();

        //业务类型
        reqMsg.setBizType(CourseBizTypeConstant.COURSE_ADD);

        //vo转entity(目标，源)
        try {
            BeanUtils.copyProperties(courseInfo, courseVo);

            String courseStr = JSON.toJSONString(courseVo);
            //数据带走
            reqMsg.setData(courseStr);

        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        byte[] bytes = reqMsg.toBytes();

        return bytes;
    }

    /**
     * 验证用户的输入是否符合条件
     *
     * @param courseVo 用户的输入信息
     * @return 验证消息
     */
    private String validateInParam(CourseVo courseVo) {
        String msg = ""; //所有提示信息

        String courseNumber = courseVo.getCode();//课程编号
        String numberBlankMsg = "课程编号必须填写！\r\n";
        String numberLengthMsg = "课程编号长度在18位以下，包含18！\r\n";
        if ("".equals(courseNumber)) {
            msg += numberBlankMsg;
        } else {
            if (courseNumber.length() > 18) {
                msg += numberLengthMsg;
            }
        }

        String courseName = courseVo.getName();//课程名称
        String nameBlankMsg = "课程名称必须填写！\r\n";
        String nameLengthMsg = "课程名称长度在18位以下，包含18！\r\n";
        if ("".equals(courseName)) {
            msg += nameBlankMsg;
        } else {
            if (courseName.length() > 18) {
                msg += nameLengthMsg;
            }
        }

        String englishName = courseVo.getEnglishName();//课程英文名称
        String englishNameLengthMsg = "课程英文名称长度在18位以下，包含18！\r\n";
        if (englishName.length() > 18) {
            msg += englishNameLengthMsg;
        }

        String versions = courseVo.getVersions(); //版本.
        String versionsLengthMsg = "版本长度在18位以下，包含18！\r\n";
        if (versions.length() > 18) {
            msg += versionsLengthMsg;
        }

        //处理返回
        if ("".equals(msg)) {
            msg = null;
        }
        if (!(msg == null)) {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setContentText(msg);
            alert.show();
        } else {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("成功");
            alert.setContentText("保存成功");
            alert.show();

            CourseInfoList pageCourseInfoList = new CourseInfoList();
            Pane pane = CourseLabLabAction.pageSkipInfo.getPane();
            Integer index = CourseLabLabAction.pageSkipInfo.getIndex();
            pane.getChildren().set(index, pageCourseInfoList);
        }

        return msg;
    }

    /**
     * 获取用户的输入
     *
     * @return 输入的信息
     */
    private CourseVo getInParams() {
        //封装成VO对象
        CourseVo courseVo = new CourseVo();
        //课程编号
        TextField codeTF = (TextField) pageAddCourse.lookup("#courseNumberTF");
        //获取课程编号输入
        String code = codeTF.getText().trim();
        courseVo.setCode(code); //给VO

        //课程名称
        TextField courseNameTF = (TextField) pageAddCourse.lookup("#courseNameTF");
        //获取课程名称输入
        String courseName = courseNameTF.getText().trim();
        courseVo.setName(courseName); //给VO

        //课程英文名称
        TextField courseEnglishNameTF = (TextField) pageAddCourse.lookup("#courseEnglishNameTF");
        //获取课程英文名称输入
        String courseEnglishName = courseEnglishNameTF.getText();
        courseVo.setEnglishName(courseEnglishName); //给VO

        //所属的学习中心
        ComboBox studyCenterCB = (ComboBox) pageAddCourse.lookup("#studyCenterCB");
        String studyCenter = (String) studyCenterCB.getValue();
        Integer studyCenterLevel = -1;
        switch (studyCenter) {
            case "北京师范大学":
                studyCenterLevel = 1;
                break;
            case "东北师范大学":
                studyCenterLevel = 2;
                break;
            case "西南大学":
                studyCenterLevel = 3;
                break;
        }
        courseVo.setStudyCenter(studyCenterLevel);

        //适合层次
        ComboBox applyLevelComboBox = (ComboBox) pageAddCourse.lookup("#applyLevelComboBox");
        //获取适合层次输入
        String value = (String) applyLevelComboBox.getValue();
        Integer level = -1;
        switch (value) {
            case "高中":
                level = 1;
                break;
            case "大专":
                level = 2;
                break;
            case "本科":
                level = 3;
                break;
            case "其他":
                level = 4;
                break;
        }
        courseVo.setApplyLevel(level);

        //版本
        TextField versionsTF = (TextField) pageAddCourse.lookup("#versionsTF");
        String versions = versionsTF.getText();
        courseVo.setVersions(versions); //给VO

        return courseVo;
    }

    /**
     * 将int数值转换成占四个字节的byte数组，本方法适用于（高位在前，低位在后）的顺序
     * 和 bytesToInt2() 配套使用
     *
     * @param value
     * @return
     */
    public static byte[] intToBytes(int value) {
        byte[] src = new byte[4];
        src[0] = (byte) ((value >> 24) & 0xFF);
        src[1] = (byte) ((value >> 16) & 0xFF);
        src[2] = (byte) ((value >> 8) & 0xFF);
        src[3] = (byte) (value & 0xFF);
        return src;
    }

    public AddPage getPageAddCourse() {
        return pageAddCourse;
    }

    public void setPageAddCourse(AddPage pageAddCourse) {
        this.pageAddCourse = pageAddCourse;
    }
}
